import { CanActivate, ExecutionContext, ForbiddenException, HttpException, Inject, Injectable } from '@nestjs/common';
import { PathMatcher } from '@/common/utils/path-matcher.util';

@Injectable()
// 校验卡密是否过期
export class ApiAuthGuard implements CanActivate {
    //取出里面所有的 apiUrl放在一个数组里
    private extractApiUrls({ userRole }, method): string[] {
        const methodDict = {
            1: 'GET',
            2: 'POST',
            3: 'PATCH',
            4: 'DELETE',
        };
        const apiList = {
            GET: [],
            POST: [],
            PATCH: [],
            DELETE: [],
        };
        userRole.forEach(({ role }) => {
            role.roleApi.forEach(({ api }) => {
                api?.apiUrl && apiList[methodDict[api.method]].push(api.apiUrl);
            });
        });
        console.log('apiList', apiList);
        return Array.from(new Set(apiList[method])); // 去除重复项并返回结果数组
    }

    async canActivate(
        context: ExecutionContext,
    ): Promise<boolean> {
        const request = context.switchToHttp().getRequest();
        const currentPath = request.url;
        // 直接调用工具类，指定组件类型为 guard
        if (PathMatcher.isExcluded(currentPath, 'guard', [])) return true;

        // 请求方式查询用户所拥有的菜单URL信息
        const apiUrls = this.extractApiUrls(request.user, request.method);
        // console.log("request.url", request.url);
        // console.log("apiUrls", apiUrls);
        // console.log("request.method", request.method);
        const requestUrl = request.url.split('?')[0];
        if (!apiUrls.includes(requestUrl)) {
            // 判断是否满足/user/4格式
            // 判断url中是否含有数字
            if (/\d+/.test(requestUrl)) {
                // 判断apiUrls中是否含有:id的url
                const isId = apiUrls.find(url => url.includes(':id'));
                if (isId) return true;
            }
            throw new ForbiddenException(`当前角色无${request.method} : ${requestUrl} 接口权限`);
        }
        return true;
    }
}
